

Portifólio Thiago Gonçalves Custódio
Calcular, analisar e interpretar os indicadores chave de performance abaixo com base nos dados fornecidos:
Indicador 1 – Faturamento Anual / Mensal e Anual por Região
Indicador 2 - Taxa Percentual de Crescimento Mensal
Indicador 3 - Clientes Ativos Por Mês
Indicador 4 - Total de Itens Comprados Por Mês
Indicador 5 - Faturamento Médio Mensal Total e exclusivo de um estado (São Paulo)
Indicador 6 - Diferença de Faturamento ao Longo do Tempo Entre Clientes Novos e Antigos
Indicador 7 - Taxa de Novos Clientes
Indicador 8 - Taxa Mensal de Retenção de Clientes
Dados fictícios, mas que podem representar a realidade.
!pip install -q -U watermark
# Imports
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib
import plotly
import matplotlib.pyplot as plt
import plotly.offline as pyoff
import plotly.graph_objs as go
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings("ignore")
%matplotlib inline
pyoff.init_notebook_mode()
# Versões dos pacotes usados neste jupyter notebook
%reload_ext watermark
%watermark -a "Thiago Gonçalves Custódio" --iversions
Author: Thiago Gonçalves Custódio plotly : 4.14.3 seaborn : 0.11.1 pandas : 1.2.2 matplotlib: 3.4.0 numpy : 1.20.1
# Carrega os dados
df = pd.read_excel("dados/dados.xlsx", header = 0)
# Visualiza os dados
df.head(4)
| ID Pedido | Data Pedido | Nome Cliente | Cidade | Pais | Regiao | Segmento | Data Entrega | Modo Entrega | Estado | Nome Produto | Desconto | Vendas | Lucro | Quantidade | Categoria | Sub-Categoria | AnoMesPedido | AnoPedido | Faturamento | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | AZ-2011-6674300 | 2011-01-04 | Devin Huddleston | Natal | Brasil | Nordeste | Consumer | 2011-01-08 | Economica | Rio Grande do Norte | Binney & Smith Sketch Pad, Easy-Erase | 0.0 | 140 | 21 | 3 | Office Supplies | Art | 201101 | 2011 | 420 |
| 1 | AZ-2011-617423 | 2011-01-05 | Daniel Burke | Recife | Brasil | Nordeste | Home Office | 2011-01-07 | Prioridade | Pernambuco | Binney & Smith Pencil Sharpener, Water Color | 0.0 | 90 | 21 | 3 | Office Supplies | Art | 201101 | 2011 | 270 |
| 2 | AZ-2011-2918397 | 2011-01-07 | Fredrick Beveridge | Palmas | Brasil | Centro-Oeste | Corporate | 2011-01-08 | Prioridade | Tocantins | Bush Floating Shelf Set, Pine | 0.1 | 155 | 36 | 1 | Furniture | Bookcases | 201101 | 2011 | 155 |
| 3 | BN-2011-3248724 | 2011-01-08 | Archer Hort | Caxias do Sul | Brasil | Sul | Consumer | 2011-01-14 | Economica | Rio Grande do Sul | Ikea Classic Bookcase, Metal | 0.6 | 987 | -1012 | 6 | Furniture | Bookcases | 201101 | 2011 | 5922 |
# Shape
df.shape
(991, 17)
# Tipos de dados
df.dtypes
ID Pedido object Data Pedido datetime64[ns] Nome Cliente object Cidade object Pais object Regiao object Segmento object Data Entrega datetime64[ns] Modo Entrega object Estado object Nome Produto object Desconto float64 Vendas int64 Lucro int64 Quantidade int64 Categoria object Sub-Categoria object dtype: object
# Describe
df.describe()
| Desconto | Vendas | Lucro | Quantidade | |
|---|---|---|---|---|
| count | 991.000000 | 991.000000 | 991.000000 | 991.000000 |
| mean | 0.071847 | 351.485368 | 45.290616 | 3.863774 |
| std | 0.124598 | 567.728055 | 161.666436 | 2.270276 |
| min | 0.000000 | 5.000000 | -1012.000000 | 1.000000 |
| 25% | 0.000000 | 57.000000 | 4.000000 | 2.000000 |
| 50% | 0.000000 | 136.000000 | 18.000000 | 3.000000 |
| 75% | 0.100000 | 375.000000 | 54.000000 | 5.000000 |
| max | 0.650000 | 5729.000000 | 1868.000000 | 14.000000 |
# Verificando valores nulos
df.isna().sum()
ID Pedido 0 Data Pedido 0 Nome Cliente 0 Cidade 0 Pais 0 Regiao 0 Segmento 0 Data Entrega 0 Modo Entrega 0 Estado 0 Nome Produto 0 Desconto 0 Vendas 0 Lucro 0 Quantidade 0 Categoria 0 Sub-Categoria 0 dtype: int64
# Range de datas do período que ocorreram os pedidos e as entregas
print('Data Mínima:', df['Data Pedido'].min())
print('Data Máxima:', df['Data Pedido'].max())
print('Data Mínima:', df['Data Entrega'].min())
print('Data Máxima:', df['Data Entrega'].max())
Data Mínima: 2011-01-04 00:00:00 Data Máxima: 2014-12-31 00:00:00 Data Mínima: 2011-01-07 00:00:00 Data Máxima: 2015-01-03 00:00:00
# Estados para os quais ocorreram vendas
df['Estado'].unique()
array(['Rio Grande do Norte', 'Pernambuco', 'Tocantins',
'Rio Grande do Sul', 'São Paulo', 'Espírito Santo',
'Rio de Janeiro', 'Ceará', 'Minas Gerais', 'Santa Catarina',
'Amazonas', 'Paraná', 'Bahia', 'Mato Grosso', 'Alagoas', 'Roraima',
'Goiás', 'Rondônia', 'Piauí', 'Amapá', 'Mato Grosso do Sul',
'Paraíba', 'Pará', 'Maranhão', 'Sergipe'], dtype=object)
Faturamento = Quantidade * Valor_Unitario
# Extrai o mês do Pedido
df['AnoMesPedido'] = df['Data Pedido'].map(lambda date: 100 * date.year + date.month)
# Extrai o ano da Pedido
df['AnoPedido'] = df['Data Pedido'].map(lambda date: date.year)
# Visualiza os dados
df.head(3)
| ID Pedido | Data Pedido | Nome Cliente | Cidade | Pais | Regiao | Segmento | Data Entrega | Modo Entrega | Estado | Nome Produto | Desconto | Vendas | Lucro | Quantidade | Categoria | Sub-Categoria | AnoMesPedido | AnoPedido | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | AZ-2011-6674300 | 2011-01-04 | Devin Huddleston | Natal | Brasil | Nordeste | Consumer | 2011-01-08 | Economica | Rio Grande do Norte | Binney & Smith Sketch Pad, Easy-Erase | 0.0 | 140 | 21 | 3 | Office Supplies | Art | 201101 | 2011 |
| 1 | AZ-2011-617423 | 2011-01-05 | Daniel Burke | Recife | Brasil | Nordeste | Home Office | 2011-01-07 | Prioridade | Pernambuco | Binney & Smith Pencil Sharpener, Water Color | 0.0 | 90 | 21 | 3 | Office Supplies | Art | 201101 | 2011 |
| 2 | AZ-2011-2918397 | 2011-01-07 | Fredrick Beveridge | Palmas | Brasil | Centro-Oeste | Corporate | 2011-01-08 | Prioridade | Tocantins | Bush Floating Shelf Set, Pine | 0.1 | 155 | 36 | 1 | Furniture | Bookcases | 201101 | 2011 |
# Calcula o faturamento
df["Faturamento"] = df["Quantidade"] * df["Vendas"]
# Visualiza os dados
df.head(3)
| ID Pedido | Data Pedido | Nome Cliente | Cidade | Pais | Regiao | Segmento | Data Entrega | Modo Entrega | Estado | ... | Desconto | Vendas | Lucro | Quantidade | Categoria | Sub-Categoria | AnoMesPedido | AnoPedido | Faturamento | TktMedio | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | AZ-2011-6674300 | 2011-01-04 | Devin Huddleston | Natal | Brasil | Nordeste | Consumer | 2011-01-08 | Economica | Rio Grande do Norte | ... | 0.0 | 140 | 21 | 3 | Office Supplies | Art | 201101 | 2011 | 420 | 140.0 |
| 1 | AZ-2011-617423 | 2011-01-05 | Daniel Burke | Recife | Brasil | Nordeste | Home Office | 2011-01-07 | Prioridade | Pernambuco | ... | 0.0 | 90 | 21 | 3 | Office Supplies | Art | 201101 | 2011 | 270 | 90.0 |
| 2 | AZ-2011-2918397 | 2011-01-07 | Fredrick Beveridge | Palmas | Brasil | Centro-Oeste | Corporate | 2011-01-08 | Prioridade | Tocantins | ... | 0.1 | 155 | 36 | 1 | Furniture | Bookcases | 201101 | 2011 | 155 | 155.0 |
3 rows × 21 columns
# Agrupa o faturamento por Ano
df_faturamento_Ano = df.groupby(['AnoPedido']).agg({'Faturamento': sum}).reset_index()
# Agrupa o faturamento por mês/ano
df_faturamento_AnoMes = df.groupby(['AnoMesPedido']).agg({'Faturamento': sum}).reset_index()
# Agrupa o faturamento por Ano/Regiao
df_faturamento_AnoRegiao = df.groupby(['AnoPedido', 'Regiao']).agg({'Faturamento': sum}).reset_index()
# Plot
# Definição dos dados no plot
plot_data = [go.Bar(x = df_faturamento_Ano['AnoPedido'],
y = df_faturamento_Ano['Faturamento'],)]
# Layout
plot_layout = go.Layout(xaxis = {"type": "category"},
title = 'Faturamento Anual')
# Plot da figura
fig = go.Figure(data = plot_data, layout = plot_layout)
pyoff.iplot(fig)
# Plot
# Definição dos dados no plot
plot_data = [go.Scatter(x = df_faturamento_AnoMes['AnoMesPedido'],
y = df_faturamento_AnoMes['Faturamento'],)]
# Layout
plot_layout = go.Layout(xaxis = {"type": "category"},
title = 'Faturamento Mensal')
# Plot da figura
fig = go.Figure(data = plot_data, layout = plot_layout)
pyoff.iplot(fig)
df_faturamento_AnoRegiao_CentroOeste = df_faturamento_AnoRegiao.query("Regiao=='Centro-Oeste'").reset_index(drop = True)
df_faturamento_AnoRegiao_Nordeste = df_faturamento_AnoRegiao.query("Regiao=='Nordeste'").reset_index(drop = True)
df_faturamento_AnoRegiao_Norte = df_faturamento_AnoRegiao.query("Regiao=='Norte'").reset_index(drop = True)
df_faturamento_AnoRegiao_Sudeste = df_faturamento_AnoRegiao.query("Regiao=='Sudeste'").reset_index(drop = True)
df_faturamento_AnoRegiao_Sul = df_faturamento_AnoRegiao.query("Regiao=='Sul'").reset_index(drop = True)
# Cria a figura
fig = go.Figure()
# Formata as barras por agrupamento
fig.add_trace(go.Bar(x = df_faturamento_AnoRegiao_CentroOeste['AnoPedido'],
y = df_faturamento_AnoRegiao_CentroOeste['Faturamento'],
name = 'Centro-Oeste',
marker_color = 'cornsilk'))
fig.add_trace(go.Bar(x = df_faturamento_AnoRegiao_Nordeste['AnoPedido'],
y = df_faturamento_AnoRegiao_Nordeste['Faturamento'],
name = 'Nordeste',
marker_color = 'coral'))
fig.add_trace(go.Bar(x = df_faturamento_AnoRegiao_Sudeste['AnoPedido'],
y = df_faturamento_AnoRegiao_Sudeste['Faturamento'],
name = 'Sudeste',
marker_color = 'cadetblue'))
fig.add_trace(go.Bar(x = df_faturamento_AnoRegiao_Sul['AnoPedido'],
y = df_faturamento_AnoRegiao_Sul['Faturamento'],
name = 'Sul',
marker_color = 'yellowgreen'))
fig.add_trace(go.Bar(x = df_faturamento_AnoRegiao_Norte['AnoPedido'],
y = df_faturamento_AnoRegiao_Norte['Faturamento'],
name = 'Norte',
marker_color = 'tomato'))
# Formata o layout
fig.update_layout(title_text = 'Faturamento Anual por Região',
xaxis = {"type": "category"},
yaxis_title = "Faturamento Anual",
barmode = 'stack')
# Mostra o gráfico
fig.show()
Taxa Percentual de Crescimento Mensal = Faturamento Mensal / Faturamento Mensal Anterior * 100
# Usamos a função pct_change() para calcular a variação percentual mensal
df_faturamento_AnoMes['CrescimentoMensal'] = df_faturamento_AnoMes['Faturamento'].pct_change()
# Tabela de dados
df_faturamento_AnoMes.head(2)
| AnoMesPedido | Faturamento | CrescimentoMensal | |
|---|---|---|---|
| 0 | 201101 | 8157 | NaN |
| 1 | 201102 | 51623 | 5.328675 |
# Plot
plot_data = [go.Scatter(x = df_faturamento_AnoMes['AnoMesPedido'],
y = df_faturamento_AnoMes['CrescimentoMensal'],)]
# Layout
plot_layout = go.Layout(xaxis = {"type": "category"},
title = 'Taxa Percentual de Crescimento Mensal')
# Plot da figura
fig = go.Figure(data = plot_data, layout = plot_layout)
pyoff.iplot(fig)
Clientes ativos são aqueles que fizeram pelo menos uma compra em cada mês.
# Usuários ativos são aqueles que fizeram pelo menos uma compra
df_ativos_mes = df.groupby('AnoMesPedido')['Nome Cliente'].nunique().reset_index()
# Dados
df_ativos_mes.head(3)
| AnoMesPedido | Nome Cliente | |
|---|---|---|
| 0 | 201101 | 7 |
| 1 | 201102 | 9 |
| 2 | 201103 | 8 |
# Plot
# Definição dos dados no plot
plot_data = [go.Bar(x = df_ativos_mes['AnoMesPedido'],
y = df_ativos_mes['Nome Cliente'],)]
# Layout
plot_layout = go.Layout(xaxis = {"type": "category"},
title = 'Clientes Ativos Por Mês')
# Plot da figura
fig = go.Figure(data = plot_data, layout = plot_layout)
pyoff.iplot(fig)
Total de itens comprados por mês.
# Agrupa os dados para calcular o total de itens comprados por mês no Brasil
df_itens_mes = df.groupby('AnoMesPedido')['Quantidade'].sum().reset_index()
# Dados
df_itens_mes.head(3)
| AnoMesPedido | Quantidade | |
|---|---|---|
| 0 | 201101 | 23 |
| 1 | 201102 | 39 |
| 2 | 201103 | 31 |
# Plot
# Definição dos dados no plot
plot_data = [go.Bar(x = df_itens_mes['AnoMesPedido'],
y = df_itens_mes['Quantidade'],)]
# Layout
plot_layout = go.Layout(xaxis = {"type": "category"},
title = 'Total de Itens Comprados Por Mês')
# Plot da figura
fig = go.Figure(data = plot_data, layout = plot_layout)
pyoff.iplot(fig)
# Calcula o faturamento médio
df_faturamento_medio = df.groupby('AnoMesPedido')['Faturamento'].mean().reset_index()
# Dados
df_faturamento_medio.head(5)
| AnoMesPedido | Faturamento | |
|---|---|---|
| 0 | 201101 | 1165.285714 |
| 1 | 201102 | 5735.888889 |
| 2 | 201103 | 939.375000 |
| 3 | 201104 | 3050.705882 |
| 4 | 201105 | 3472.111111 |
# Plot
# Definição dos dados no plot
plot_data = [go.Bar(x = df_faturamento_medio['AnoMesPedido'],
y = df_faturamento_medio['Faturamento'],)]
# Layout
plot_layout = go.Layout(xaxis = {"type": "category"},
title = 'Faturamento Médio Mensal')
# Plot da figura
fig = go.Figure(data = plot_data, layout = plot_layout)
pyoff.iplot(fig)
# Cria um dataframe somente com dados do São Paulo
dados_SaoPaulo = df.query("Estado=='São Paulo'").reset_index(drop = True)
# Calcula o faturamento médio de São Paulo
df_faturamento_medio_sp = dados_SaoPaulo.groupby('AnoMesPedido')['Faturamento'].mean().reset_index()
# Dados
df_faturamento_medio_sp.head(3)
| AnoMesPedido | Faturamento | |
|---|---|---|
| 0 | 201101 | 116.000000 |
| 1 | 201102 | 181.166667 |
| 2 | 201103 | 464.000000 |
# Plot
# Definição dos dados no plot
plot_data = [go.Bar(x = df_faturamento_medio_sp['AnoMesPedido'],
y = df_faturamento_medio_sp['Faturamento'],)]
# Layout
plot_layout = go.Layout(xaxis = {"type": "category"},
title = 'Faturamento Total Mensal em um Estado (São Paulo)')
# Plot da figura
fig = go.Figure(data = plot_data, layout = plot_layout)
pyoff.iplot(fig)
Para calcular esse indicador precisaremos de um pouco de criatividade.
Vamos considerar cliente novo aquele com baixo volume de compras e cliente antigo aquele com alto volume de compras.
# Vamos encontrar a data de menor volume de compras de cada cliente
df_compra_minima = df.groupby('Nome Cliente')["Data Pedido"].min().reset_index()
# Ajustamos os nomes das colunas
df_compra_minima.columns = ['Nome Cliente', 'Data_Menor_Compra']
# Vamos extrair o mês em que ocorreu o menor volume de compras de cada cliente
df_compra_minima['Mes_Menor_Compra_Mensal'] = df_compra_minima['Data_Menor_Compra'].map(lambda date: 100 * date.year + date.month)
# Dados
df_compra_minima.head()
| Nome Cliente | Data_Menor_Compra | Mes_Menor_Compra_Mensal | |
|---|---|---|---|
| 0 | Aaron Bootman | 2013-08-13 | 201308 |
| 1 | Aaron Cunningham | 2012-08-31 | 201208 |
| 2 | Aaron Davey | 2012-06-06 | 201206 |
| 3 | Abbie Perry | 2014-09-25 | 201409 |
| 4 | Abby Colebe | 2011-09-19 | 201109 |
# Vamos fazer um merge entre o dataset original e o dataset de volume de compras
dados_compras = pd.merge(df, df_compra_minima, on = "Nome Cliente")
dados_compras.head()
| ID Pedido | Data Pedido | Nome Cliente | Cidade | Pais | Regiao | Segmento | Data Entrega | Modo Entrega | Estado | ... | Lucro | Quantidade | Categoria | Sub-Categoria | AnoMesPedido | AnoPedido | Faturamento | TktMedio | Data_Menor_Compra | Mes_Menor_Compra_Mensal | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | AZ-2011-6674300 | 2011-01-04 | Devin Huddleston | Natal | Brasil | Nordeste | Consumer | 2011-01-08 | Economica | Rio Grande do Norte | ... | 21 | 3 | Office Supplies | Art | 201101 | 2011 | 420 | 140.0 | 2011-01-04 | 201101 |
| 1 | AZ-2014-381698 | 2014-06-23 | Devin Huddleston | Ji-Paraná | Brasil | Norte | Consumer | 2014-06-27 | Economica | Rondônia | ... | 16 | 4 | Furniture | Bookcases | 201406 | 2014 | 2868 | 717.0 | 2011-01-04 | 201101 |
| 2 | BN-2014-2717006 | 2014-08-22 | Devin Huddleston | Serra | Brasil | Sudeste | Consumer | 2014-08-28 | Economica | Espírito Santo | ... | -28 | 3 | Technology | Machines | 201408 | 2014 | 897 | 299.0 | 2011-01-04 | 201101 |
| 3 | AZ-2011-617423 | 2011-01-05 | Daniel Burke | Recife | Brasil | Nordeste | Home Office | 2011-01-07 | Prioridade | Pernambuco | ... | 21 | 3 | Office Supplies | Art | 201101 | 2011 | 270 | 90.0 | 2011-01-05 | 201101 |
| 4 | AZ-2011-2918397 | 2011-01-07 | Fredrick Beveridge | Palmas | Brasil | Centro-Oeste | Corporate | 2011-01-08 | Prioridade | Tocantins | ... | 36 | 1 | Furniture | Bookcases | 201101 | 2011 | 155 | 155.0 | 2011-01-07 | 201101 |
5 rows × 23 columns
# Vamos criar uma nova coluna de tipo de usuário e preencher como Novo
dados_compras['TipoUsuario'] = 'Novo'
# Dados
dados_compras['TipoUsuario'].value_counts()
Novo 991 Name: TipoUsuario, dtype: int64
# Dados
dados_compras.head(3)
| ID Pedido | Data Pedido | Nome Cliente | Cidade | Pais | Regiao | Segmento | Data Entrega | Modo Entrega | Estado | ... | Quantidade | Categoria | Sub-Categoria | AnoMesPedido | AnoPedido | Faturamento | TktMedio | Data_Menor_Compra | Mes_Menor_Compra_Mensal | TipoUsuario | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | AZ-2011-6674300 | 2011-01-04 | Devin Huddleston | Natal | Brasil | Nordeste | Consumer | 2011-01-08 | Economica | Rio Grande do Norte | ... | 3 | Office Supplies | Art | 201101 | 2011 | 420 | 140.0 | 2011-01-04 | 201101 | Novo |
| 1 | AZ-2014-381698 | 2014-06-23 | Devin Huddleston | Ji-Paraná | Brasil | Norte | Consumer | 2014-06-27 | Economica | Rondônia | ... | 4 | Furniture | Bookcases | 201406 | 2014 | 2868 | 717.0 | 2011-01-04 | 201101 | Antigo |
| 2 | BN-2014-2717006 | 2014-08-22 | Devin Huddleston | Serra | Brasil | Sudeste | Consumer | 2014-08-28 | Economica | Espírito Santo | ... | 3 | Technology | Machines | 201408 | 2014 | 897 | 299.0 | 2011-01-04 | 201101 | Antigo |
3 rows × 24 columns
# Um cliente antigo é aquele cujo volume de compras no mês é maior que o volume mínimo
# Se for verdadeiro, mudamos a coluna TipoUsuario para "Antigo" e se não, mantemos como "Novo"
dados_compras.loc[dados_compras['AnoMesPedido'] > dados_compras['Mes_Menor_Compra_Mensal'], 'TipoUsuario'] = 'Antigo'
# Dados
dados_compras['TipoUsuario'].value_counts()
Novo 577 Antigo 414 Name: TipoUsuario, dtype: int64
# Agora calculamos o faturamento por tipo de usuário por mês
df_faturamento_user_mes = dados_compras.groupby(['AnoMesPedido', 'TipoUsuario'])['Faturamento'].sum().reset_index()
# Dados
df_faturamento_user_mes
| AnoMesPedido | TipoUsuario | Faturamento | |
|---|---|---|---|
| 0 | 201101 | Novo | 8157 |
| 1 | 201102 | Novo | 51623 |
| 2 | 201103 | Novo | 7515 |
| 3 | 201104 | Novo | 51862 |
| 4 | 201105 | Novo | 31249 |
| ... | ... | ... | ... |
| 85 | 201410 | Novo | 753 |
| 86 | 201411 | Antigo | 97656 |
| 87 | 201411 | Novo | 14982 |
| 88 | 201412 | Antigo | 31668 |
| 89 | 201412 | Novo | 16846 |
90 rows × 3 columns
# Plot
# Definição dos dados no plot
plot_data = [go.Scatter(x = df_faturamento_user_mes.query("TipoUsuario == 'Antigo'")['AnoMesPedido'],
y = df_faturamento_user_mes.query("TipoUsuario == 'Antigo'")['Faturamento'],
name = 'Cliente Antigo'),
go.Scatter(x = df_faturamento_user_mes.query("TipoUsuario == 'Novo'")['AnoMesPedido'],
y = df_faturamento_user_mes.query("TipoUsuario == 'Novo'")['Faturamento'],
name = 'Cliente Novo')]
# Layout
plot_layout = go.Layout(xaxis = {"type": "category"},
title = 'Diferença de Faturamento ao Longo do Tempo Entre Clientes Novos e Antigos')
# Plot da figura
fig = go.Figure(data = plot_data, layout = plot_layout)
pyoff.iplot(fig)
Como definimos clientes novos e antigos no indicador 6, agora podemos usar os dados e calcular a proporção de novos clientes ao longo do tempo.
# Calcula a taxa de novos clientes
df_taxa_novos_clientes = dados_compras.query("TipoUsuario == 'Novo'").groupby(['AnoMesPedido'])['Nome Cliente'].nunique() / dados_compras.query("TipoUsuario == 'Antigo'").groupby(['AnoMesPedido'])['Nome Cliente'].nunique()
# Ajustamos índice e removemos valores ausentes
df_taxa_novos_clientes = df_taxa_novos_clientes.reset_index()
df_taxa_novos_clientes = df_taxa_novos_clientes.dropna()
# Dados
df_taxa_novos_clientes.head(5)
| AnoMesPedido | Nome Cliente | |
|---|---|---|
| 6 | 201107 | 5.0 |
| 7 | 201108 | 20.0 |
| 8 | 201109 | 2.8 |
| 9 | 201110 | 7.0 |
| 10 | 201111 | 4.0 |
# Plot
# Definição dos dados no plot
plot_data = [go.Bar(x = df_taxa_novos_clientes['AnoMesPedido'],
y = df_taxa_novos_clientes['Nome Cliente'],)]
# Layout
plot_layout = go.Layout(xaxis = {"type": "category"},
title = 'Taxa de Novos Clientes')
# Plot da figura
fig = go.Figure(data = plot_data, layout = plot_layout)
pyoff.iplot(fig)
Taxa Mensal de Retenção de Clientes = Clientes do Mês Anterior / Total de Clientes Ativos
# Agrupamos os dados por cliente e mês e somamos o faturamento
dados_compras_clientes = dados_compras.groupby(['Nome Cliente', 'AnoMesPedido'])['Faturamento'].sum().reset_index()
# Dados
dados_compras_clientes.head()
| Nome Cliente | AnoMesPedido | Faturamento | |
|---|---|---|---|
| 0 | Aaron Bootman | 201308 | 735 |
| 1 | Aaron Bootman | 201310 | 3792 |
| 2 | Aaron Cunningham | 201208 | 46 |
| 3 | Aaron Cunningham | 201401 | 202 |
| 4 | Aaron Cunningham | 201406 | 129 |
# Agora definimos a retenção com uma tabela cruzada
df_ret = pd.crosstab(dados_compras_clientes['Nome Cliente'], dados_compras_clientes['AnoMesPedido']).reset_index()
# Dados
df_ret.head()
| AnoMesPedido | Nome Cliente | 201101 | 201102 | 201103 | 201104 | 201105 | 201106 | 201107 | 201108 | 201109 | ... | 201403 | 201404 | 201405 | 201406 | 201407 | 201408 | 201409 | 201410 | 201411 | 201412 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Aaron Bootman | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | Aaron Cunningham | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | Aaron Davey | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | Abbie Perry | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| 4 | Abby Colebe | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
5 rows × 49 columns
# Extraímos os meses
meses = df_ret.columns[2:]
meses
Index([201102, 201103, 201104, 201105, 201106, 201107, 201108, 201109, 201110,
201111, 201112, 201201, 201202, 201203, 201204, 201205, 201206, 201207,
201208, 201209, 201210, 201211, 201212, 201301, 201302, 201303, 201304,
201305, 201306, 201307, 201308, 201309, 201310, 201311, 201312, 201401,
201402, 201403, 201404, 201405, 201406, 201407, 201408, 201409, 201410,
201411, 201412],
dtype='object', name='AnoMesPedido')
# O loop abaixo vai calcular a retenção ao longo dos meses
# Lista para gravar o resulatdo
lista_ret = []
# Loop
for i in range(len(meses)-1):
dados_retencao = {}
mes_corrente = meses[i+1]
mes_anterior = meses[i]
dados_retencao['AnoMes'] = int(mes_corrente)
dados_retencao['TotalUser'] = df_ret[mes_corrente].sum()
dados_retencao['TotalRetido'] = df_ret[(df_ret[mes_corrente] > 0) & (df_ret[mes_anterior] > 0)][mes_corrente].sum()
lista_ret.append(dados_retencao)
lista_ret
[{'AnoMes': 201103, 'TotalUser': 8, 'TotalRetido': 0},
{'AnoMes': 201104, 'TotalUser': 16, 'TotalRetido': 0},
{'AnoMes': 201105, 'TotalUser': 9, 'TotalRetido': 0},
{'AnoMes': 201106, 'TotalUser': 24, 'TotalRetido': 0},
{'AnoMes': 201107, 'TotalUser': 6, 'TotalRetido': 0},
{'AnoMes': 201108, 'TotalUser': 21, 'TotalRetido': 1},
{'AnoMes': 201109, 'TotalUser': 19, 'TotalRetido': 1},
{'AnoMes': 201110, 'TotalUser': 8, 'TotalRetido': 0},
{'AnoMes': 201111, 'TotalUser': 20, 'TotalRetido': 1},
{'AnoMes': 201112, 'TotalUser': 20, 'TotalRetido': 0},
{'AnoMes': 201201, 'TotalUser': 11, 'TotalRetido': 1},
{'AnoMes': 201202, 'TotalUser': 11, 'TotalRetido': 0},
{'AnoMes': 201203, 'TotalUser': 17, 'TotalRetido': 0},
{'AnoMes': 201204, 'TotalUser': 5, 'TotalRetido': 0},
{'AnoMes': 201205, 'TotalUser': 8, 'TotalRetido': 0},
{'AnoMes': 201206, 'TotalUser': 28, 'TotalRetido': 1},
{'AnoMes': 201207, 'TotalUser': 13, 'TotalRetido': 1},
{'AnoMes': 201208, 'TotalUser': 36, 'TotalRetido': 0},
{'AnoMes': 201209, 'TotalUser': 26, 'TotalRetido': 2},
{'AnoMes': 201210, 'TotalUser': 18, 'TotalRetido': 0},
{'AnoMes': 201211, 'TotalUser': 27, 'TotalRetido': 1},
{'AnoMes': 201212, 'TotalUser': 30, 'TotalRetido': 0},
{'AnoMes': 201301, 'TotalUser': 16, 'TotalRetido': 1},
{'AnoMes': 201302, 'TotalUser': 25, 'TotalRetido': 0},
{'AnoMes': 201303, 'TotalUser': 12, 'TotalRetido': 1},
{'AnoMes': 201304, 'TotalUser': 19, 'TotalRetido': 1},
{'AnoMes': 201305, 'TotalUser': 13, 'TotalRetido': 1},
{'AnoMes': 201306, 'TotalUser': 27, 'TotalRetido': 0},
{'AnoMes': 201307, 'TotalUser': 14, 'TotalRetido': 0},
{'AnoMes': 201308, 'TotalUser': 38, 'TotalRetido': 1},
{'AnoMes': 201309, 'TotalUser': 30, 'TotalRetido': 3},
{'AnoMes': 201310, 'TotalUser': 12, 'TotalRetido': 0},
{'AnoMes': 201311, 'TotalUser': 29, 'TotalRetido': 0},
{'AnoMes': 201312, 'TotalUser': 29, 'TotalRetido': 0},
{'AnoMes': 201401, 'TotalUser': 28, 'TotalRetido': 1},
{'AnoMes': 201402, 'TotalUser': 14, 'TotalRetido': 0},
{'AnoMes': 201403, 'TotalUser': 14, 'TotalRetido': 0},
{'AnoMes': 201404, 'TotalUser': 26, 'TotalRetido': 0},
{'AnoMes': 201405, 'TotalUser': 23, 'TotalRetido': 0},
{'AnoMes': 201406, 'TotalUser': 33, 'TotalRetido': 1},
{'AnoMes': 201407, 'TotalUser': 6, 'TotalRetido': 0},
{'AnoMes': 201408, 'TotalUser': 42, 'TotalRetido': 0},
{'AnoMes': 201409, 'TotalUser': 36, 'TotalRetido': 3},
{'AnoMes': 201410, 'TotalUser': 18, 'TotalRetido': 1},
{'AnoMes': 201411, 'TotalUser': 37, 'TotalRetido': 1},
{'AnoMes': 201412, 'TotalUser': 38, 'TotalRetido': 0}]
# Dados
df_ret_final = pd.DataFrame(lista_ret)
df_ret_final.head()
| AnoMes | TotalUser | TotalRetido | |
|---|---|---|---|
| 0 | 201103 | 8 | 0 |
| 1 | 201104 | 16 | 0 |
| 2 | 201105 | 9 | 0 |
| 3 | 201106 | 24 | 0 |
| 4 | 201107 | 6 | 0 |
Agora calculamos a proporção para encontrar o indicador.
# Calculamos o indicador
df_ret_final['TaxaRetencao'] = df_ret_final['TotalRetido'] / df_ret_final['TotalUser']
df_ret_final.head(5)
| AnoMes | TotalUser | TotalRetido | TaxaRetencao | |
|---|---|---|---|---|
| 0 | 201103 | 8 | 0 | 0.0 |
| 1 | 201104 | 16 | 0 | 0.0 |
| 2 | 201105 | 9 | 0 | 0.0 |
| 3 | 201106 | 24 | 0 | 0.0 |
| 4 | 201107 | 6 | 0 | 0.0 |
# Plot
# Definição dos dados no plot
plot_data = [go.Scatter(x = df_ret_final.query("AnoMes < 201112")['AnoMes'],
y = df_ret_final.query("AnoMes < 201112")['TaxaRetencao'],
name = "taxa")]
# Layout
plot_layout = go.Layout(xaxis = {"type": "category"},
title = 'Taxa Mensal de Retenção de Clientes')
# Plot da figura
fig = go.Figure(data = plot_data, layout = plot_layout)
pyoff.iplot(fig)
Conforme acima tivemos êxito calcular, analisar e interpretar os indicadores chave de performance abaixo com base nos dados fornecidos.
Caso tenha alguma dúvida ou sugestão, entre em contato.